"""
Система заметок для Чио.

- Работает и для личных сообщений, тогда замтки считаются локальными.
- Список заметок хранится отдельно для кждого чата.
- Просмотр заметок в чате: локальные, ваши, по дате, по имени.
- Удаление своих заметок по одной или сразу все.
- Управление ссылками на заметки (вызывать заметки по ![ССЫЛКА])

Author: Milinuri Nirvalen
Ver: 1.0.3 (5)
"""

import datetime
import time

from chiori import Config
from chiori import Plugin
from chiori import fcheck


p = Plugin(name='заметки', path='data/notes/',
	args={
		'name': 'уникальное имя заметки, одно слово. (aaa, rules, O_o)',
		'link': 'уникальное имя для ссылки на заметку (правила, приветствие, памятка, сочинение)'
	})


helpnote = {'links': [], 'date': 273291180, 'favorites': [], 'author': "~",
	"author_str":"system", "text":f'''инструкция по использованию заметок.
-- посмотреть список команд: "/help notes"

[ просмотр заметок ]
-- /note <name> - просмотр заметки
-- /notes <pattern> - просмотр списка заметок
| <pattern> - тип списка, можно указать:
| -- по умолчанию: сортировка по имени
| -- my / мои / m: среди списка ваших заметок
| -- date / d / дата: сортировка по дате

[ создание/удаление заметок ]
-- /note <name> <text> - создание заметки
-- /rwnote <name> <text> - создать/перезаписать заметку
| если заметки нету, она будет создана
| (!) если заместка (ваша) существует, она будет перезаписана (замена /rmnote + /note)
| (!) после перезаписи, все ссылки стираются
-- /rwnote <name> <text> - создание заметки (с перезаписью)
-- /clearnotes <- "/rmnote all" - удаляет все ваши заметки
-- /rmnote <names> - удалить заметка
| <name> - имена заметок, разделяемые пробелом
| all / my / m / мои / * - удалить все ваши заметки
| (!) вы можете удалить только свои заметки

[ ссылки на заметку ]
Привязка ID заметки к имени (!привила -> /note chat_rules)
/notelink <name> <links> - создать ссылку(и) (alias) на заметку
/rmnotelink <name> <links/all> - удалить ссылку(и) на заметку
| (!) all / * / все - удалить все ссылки на заметку
'''}

# func
# ====

def get_data(event, local=False):
	if local:
		path = f'data/notes/{event.get("from.id")}.toml'
	else:
		path = f'data/notes/{event.get("to.id")}.toml'

	return Config(None, {}, path)


def get_my_notes(event, local=False):
	c = get_data(event, local)

	if local:
		return c

	res = []
	for k, v in c.file_data.items():
		if v['author'] == event.get('from.id'):
			res.append(k)
	return res


def get_links(event):
	c = get_data(event).file_data
	links = {}

	for k, v in c.items():
		for x in v["links"]:
			links[x] = k
	return links


def note_data(note, name):

	if len(note["links"]):
		links = f'\n🔑 имена: {", ".join(note["links"])}'
	else:
		links = f'\n🔑 у заметки нету имён'

	if len(note["favorites"]):
		favorites = f'\n⭐ заметку отметили {len(note["favorites"])} чел.'
	else:
		favorites = f''

		# {'favorites': [], 'author': 628901097}
	return f'''📃 заметка "{name}"
📅 создана: {time.ctime(note["date"])}
✏ автор: {note["author_str"]} <{note["author"]}>{favorites}{links}

[содержимое]
{note["text"]}'''

def note_status(note, print_date=False, print_author=True):

	if len(note["links"]):
		links = f' {len(note["links"])}🔑'
	else:
		links = f''

	favorites = f'{len(note["favorites"])}⭐'
	date = f' 📅 {time.ctime(note["date"])}'
	text = f'{favorites}{links}'

	if print_author:
		text += f' ✏{note["author_str"]} <{note["author"]}>'
	if print_date:
		text += date
	return text


# handlers
# ========

@p.eventHandler('before')
async def _(event, ctx):
	if event.get('text') and event.get('text')[0] == '!':
		text = event.get('text')[1:]

		c = get_data(event).file_data
		nl = get_links(event)

		if text in nl:
			await ctx.message(note_data(c[nl[text]], nl[text]))


# commands
# ========

@p.command('notes', 'заметки', usage='список заметок')
async def notesList(event, ctx):
	c = get_data(event).file_data

	if len(c):
		my_notes = False
		sort_from_date = False
		local = True
		sort_key = lambda x: x[0]

		for a in ctx.args:
			if a in ['my', 'm', 'мои']:
				my_notes = True
			if a in ['date', 'd', 'дата', 'дате']:
				sort_key = lambda x: x[1]["date"]

			if a in ['local', 'l', 'лс']:
				local = True

		if local:
			text = f'📖 список локальных заметок (): '
		elif my_notes:

			text = f'📖 список ваших заметок (по имени): '
			for k in get_my_notes(event):
				text += f'\n-- "{c[k]}" {note_status(v, True, False)}'

		else:
			if sort_from_date:
				text = f'📖 список заметок ({len(c)}шт. / по дате): '
				for k, v in sorted(c.items(), key=lambda x: x[1]["date"], reverse=True):
					text += f'\n-- "{k}" {note_status(v, True)}'

			else:
				text = f'📖 список заметок ({len(c)}шт. / по имени): '
				for k, v in sorted(c.items()):
					text += f'\n-- "{k}" {note_status(v)}'

	else:
		text = f'📖 в беседе нету заметок.'

	await ctx.message(text)


@p.command('<note ++/rw>',
	usage='<name> <text> создать/перезаписать заметку')
async def reWriteNote(event, ctx):
	c = get_data(event)
	mn = get_my_notes(event)

	if len(ctx.args) > 1:
		if ctx.args[0] not in c.file_data or ctx.args[0] in mn:
			text = ctx.sargs.split(' ',1)[1][:2000]
			author = f"{event.get('from.first_name')} {event.get('from.last_name')}"

			c.file_data[ctx.args[0]] = {'text':text, 'links':[],
				"date":ctx.now, "favorites":[], "author_str":author,
				"author":event.get('from.id')}

			text = f'📝 заметка "{ctx.args[0]}" создана/перезаписана'
			c.save()
		else:
			text = f'Возможно "{ctx.args[0]}" уже занято, или вы пытаетесь перезаписать чужую заметку'
		await ctx.message(text)
	else:
		await ctx.message(f'для создания заметки нужно указать имя и текст\n/rwnote aaa место для вашей рекламы')


@p.command('note', '<note(s) a/add>',
	usage='<name> <text> создать заметку')
async def createNote(event, ctx):
	c = get_data(event)

	if len(ctx.args) > 1:
		if ctx.args[0] in c.file_data:
			note = c.file_data[ctx.args[0]]
			text = f'📖 имя "{ctx.args[0]}" уже занято\n-- {note_status(note)}'

		else:
			text = ctx.sargs.split(' ',1)[1][:2000]
			author = f"{event.get('from.first_name')} {event.get('from.last_name')}"

			c.file_data[ctx.args[0]] = {'text':text, 'links':[],
				"date":ctx.now, "favorites":[], "author_str":author,
				"author":event.get('from.id')}

			text = f'📝 заметка "{ctx.args[0]}" создана'
			c.save()

	elif ctx.args:
		if ctx.args[0] == 'help':
			text = note_data(helpnote, 'help note')

		elif ctx.args[0] in c.file_data:
			text = note_data(c.file_data[ctx.args[0]], ctx.args[0])

		else:
			text = f'📖 заметка "{ctx.args[0]}" не найдена'
	else:
		text = "📖 пожалуйста укажите имя и текст заметки"

	await ctx.message(text)


@p.command('<note(s) d/del(ete)/rm/remove>',
	usage='<names/*> удалить вашу заметку')
async def removeNotes(event, ctx):
	c = get_data(event)

	if ctx.sargs in ['all', 'my', 'мои', '*']:
		i = 0
		for k, v in list(c.file_data.items()):
			if v["author"] == event.get('from.id'):
				del c.file_data[k]
				i += 1
		c.save()
		await ctx.message(f'🗑 все ваши заметки удалены ({i}шт.)')

	elif ctx.args:
		text = ''
		for a in ctx.args:

			if a in c.file_data:
				note = c.file_data[a]
				if note["author"] == event.get('from.id'):
					del c.file_data[a]
					text += f'\n🗑 заметка "{a}" удалена'
				else:
					text += f'\n"{a}" 🗑 вы можете удалять только свои заметки\n/notes my - список ваших заметок'
			else:
				text += f'\n📖 заметка "{a}" не найдена'
		c.save()
		await ctx.message(text)
	else:
		await ctx.message('🗑 для удаления заметки пропишите её имя\nпример: /rmnote aaa')


@p.command('<clear/delall/dall/rmall notes>',
	usage='удалить все ваши заметки')
async def removeAllNotes(event, ctx):
	c = get_data(event)
	i = 0
	for k, v in list(c.file_data.items()):
		if v["author"] == event.get('from.id'):
			del c.file_data[k]
			i += 1
		c.save()
	await ctx.message(f'🗑 все ваши заметки удалены ({i}шт.)')


@p.command('<link note>', 'addnotelink',
	usage='<name> <links> создать ссылку на заметку')
async def addNoteLinks(event, ctx):
	c = get_data(event)
	mn = get_my_notes(event)
	nl = get_links(event)

	if len(ctx.args) > 1:
		if ctx.args[0] in mn:
			text = ''
			for a in ctx.args[1:]:

				if a not in nl:
					c.file_data[ctx.args[0]]["links"].append(a)
					text += f'\n🔗 создана ссылка "{a}" -> "{ctx.args[0]}"'
				else:
					note = c.file_data[nl[a]]
					text += f'\n🔗 ссылка "{a}" уже связана с "{nl[a]}" {note_status(note)}'

			c.save()
			await ctx.message(text)
		else:
			await ctx.message('🔗 вы можете создать ссылки только для свомх заметок')
	else:
		await ctx.message('🔗 для создания ссылки на заметку укажите имя заметки и имя ссылки\n/linknote price_list суши')


@p.command('<rm/del notelink>',
	usage='<name> <links> удалить ссылки на заметку')
async def removeNoteLinks(event, ctx):
	c = get_data(event)
	mn = get_my_notes(event)
	nl = get_links(event)

	if len(ctx.args) > 1:
		if ctx.args[0] in mn:
			text = ''
			for a in ctx.args[1:]:

				if a in ['all', '*', 'все']:
					c.file_data[ctx.args[0]]["links"] = []
					text += f'\n🔗 удалена все ссылки на "{ctx.args[0]}"'

				elif a in nl:
					c.file_data[ctx.args[0]]["links"].remove(a)
					text += f'\n🔗 удалена ссылка "{a}" -> "{ctx.args[0]}"'

				else:
					note = c.file_data[nl[a]]
					text += f'\n🔗 ссылка "{a}" не связана связана с "{nl[a]}" {note_status(note)}'

			c.save()
			await ctx.message(text)
		else:
			await ctx.message('🔗 вы можете удалять ссылки только для свомх заметок')
	else:
		await ctx.message('🔗 для удаления ссылки на заметку укажите имя заметки и имя ссылки\n/rmnotelink price_list суши')
